// transactions.cpp
// Customizer
// Protea Customizer / Business Logic for managing transactions
// Copyright (C) 2003, 2004, 2005 eXegeSys, Inc.
// Copyright (C) 2008 Bruce A. James
//
// This program is part of the Protea Project.
//
// The Protea Project is free software; you can redistribute it and/or modify it 
// under the terms of the GNU General Public License as published by the 
// Free Software Foundation, either version 3 of the License, or (at your 
// option) any later version.
//
// The Protea Project is distributed in the hope that it will be useful, but 
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
// for more details.
// 
// You should have received a copy of the GNU General Public License along 
// with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// Please send correspondence to:
//
// theproteaproject@gmail.com
//

#include "customizer.h"

//////////////////////////////////////////////////////////////////////////////
//
// Transaction Transactions :)
//
//////////////////////////////////////////////////////////////////////////////

//@ SEC 2

//@ CHA Chg Transaction
//@ COD ChgTransaction
//@ NUM 26
//@ CRI TRANS_CODE
//@ TAB TRANSACTION_DEFN Write
//
//@ GEN Change Transaction will add a transaction for an application
//
TRANSACTION_CODE( ChangeTransaction )
{
	XCBuffer* buf = NULL;
	XCBuffer* orig = NULL;
	XCBuffer* uebuf = NULL;
	XCBuffer* uebuf_orig = NULL;

	//@ GRS Start the transaction
	START_TXN( ChangeTransaction );
		bool ReviewOnly = txnvars.buffer->IsBlank( 1, FLD_TRANS_CODE );

		//@ Create Literal Defn buffer
		buf = App->CreateBuffer( FMT_TRANSACTION_DEFN );

		//@ Move screen info to transaction buffer
		buf->MoveCorresponding( txnvars.buffer, txnvars.Errors );
		txnvars.Errors->Check();

		START_DB_TXN();
			//@ SUB TransactionDefnVerify to verify that application can be added
			TransactionVerify( buf, VERIFY_CHANGE, &txnvars );

			//@ Check for errors
			txnvars.Errors->Check();

			if (!ReviewOnly) {
				orig = buf->Copy();
				buf->MoveCorresponding( txnvars.buffer, NULL, true );
				buf->MoveField( orig, FLD_TRANS_NUMBER );
				buf->MarkChanges( orig );
				if (buf->IsChanged()) {
					//@ SUB TransactionDefnChange to change the transaction
					TransactionChange( buf, orig, &txnvars );
				};
			} else
				txnvars.buffer->MoveCorresponding( buf, txnvars.Errors );

			//@ Transaction may also submit multiple UE buffers for change...
			if (txnvars.detailcount) {
				uebuf = App->CreateBuffer( FMT_USER_EXIT_DEFNS, false );
				uebuf->MoveField( buf, FLD_APPL_NBR );
				uebuf_orig = uebuf->Copy();

				for (int i=0; i<txnvars.detailcount; i++) {
					XCBuffer* temp = txnvars.detail[i];

					// Find user exit name
					if (!LookupNumberFromName( &txnvars, temp, uebuf_orig, FLD_USER_EXIT_NUMBER, FLD_USER_EXIT_NAME, FMT_USER_EXIT_DEFNS ))
						RAISETOOLSERROR( 1 );

					// Retrieve the user exit record
					UserExitDefnsRetrieve( uebuf_orig, &txnvars );
					uebuf->MoveCorresponding( uebuf_orig, txnvars.Errors );

					// Only allow changes to the active flag from here...
					uebuf->MoveField( temp, FLD_USER_EXIT_ACTIVE, true );

					// Update the record
					UserExitDefnsChange( uebuf, uebuf_orig, &txnvars );
				};
			};

			App->TransResponse( txnvars.result, txnvars.buffer, TRANS_HEADER_TYPE );

			LOG_TRANSACTION();

		END_DB_TXN();

	CLEANUP_TXN();
		App->CleanupObjects( 4, &buf, &orig, &uebuf, &uebuf_orig );
	END_TXN();
	//@ GRE End the transaction
};



//
//@ CHA ValidTransactionBuffer
//@ COD ValidTransactionBuffer
//@ NUM 190
//@ CRI APPL_NBR
//@ TAB TRANSACTION_DEFN Read
//
//@ GEN ValidTransactionBuffer will return success/failure based on whether the
//@ GEN given buffer will work for a particular transaction
//
TRANSACTION_CODE( ValidTransactionBuffer ) {
	XCBuffer* TransBuf = NULL;

	//@ GRS Start the transaction
	START_TXN( ValidTransactionBuffer );
//		XCSQLGen* query = txnvars.query;

		//@ Create transaction defn buffer
		TransBuf = App->CreateBuffer( FMT_TRANSACTION_DEFN, false );

		//@ Move screen info to transaction buffer
		TransBuf->MoveCorresponding( txnvars.buffer, txnvars.Errors );

		START_DB_TXN();
			TransactionVerify( TransBuf, VERIFY_REVIEW, &txnvars );
			txnvars.Errors->Check();
		END_DB_TXN();

	CLEANUP_TXN();
		App->CleanupObjects( 1, &TransBuf );
	END_TXN();
	//@ GRE End the transaction
};
